/**
	Author: Nathan
*/
#include "gtest/gtest.h"
#include "../../KittingCell/NestAgent.h"
#include "LaneAgentMock.h"
#include "GUINestMock.h"
#include "CameraAgentMock.h"
#include "PartRobotAgentMock.h"

class NestAgentTest : public ::testing::Test {

protected:

  NestAgentTest() : agent("Nest Test") {

  }
	
  virtual void SetUp() {
	  agent.testing = true;
	  agent.setPartRobot(&partRobot);
	  agent.setCamera(&camera);
	  agent.setLane(&lane); 
	  agent.setGUI(&guiNest);
  }

  NestAgent agent;

  PartRobotAgentMock partRobot;
  
  CameraAgentMock camera;

  LaneAgentMock lane;

  GUINestMock guiNest;
  
  bool runScheduler(){
    return agent.pickAndExecuteAnAction();
  }
    
  NestAgent::NestState myState() {
	return agent.state;
  }
  
  PartType myPartType() {
	return agent.partType;
  }

  /*Agent::ClientStatus getNextStat(){
	  return agent->nextStatus;
  }*/
};

TEST_F(NestAgentTest, InitialTest){
	EXPECT_EQ(myState(),NestAgent::NestState::None);
	EXPECT_EQ(myPartType(),PartType::EMPTY);
}

TEST_F(NestAgentTest, SchedulerInitialReturnTest){
	EXPECT_EQ(runScheduler(),false);
}

TEST_F(NestAgentTest, TestingSettingPartTypeFromRobot){
	PartType partA = PartType::A;
	EXPECT_EQ(myPartType(),PartType::EMPTY);
	agent.msgPleaseGetParts(partA);
	EXPECT_EQ(myPartType(),partA);
}

TEST_F(NestAgentTest, SchedulerReturnTestWithPartType){
	PartType partA = PartType::A;
	agent.msgPleaseGetParts(partA);
	EXPECT_EQ(myPartType(),partA);
	EXPECT_EQ(myState(),NestAgent::NestState::Ready_To_Purge);
	EXPECT_EQ(runScheduler(),true);
	EXPECT_FALSE(runScheduler());
}

TEST_F(NestAgentTest, NestBelievesItIsFullTest){
	PartType partA = PartType::A;
	agent.msgPleaseGetParts(partA);
	agent.msgIThinkYoureFull();
	EXPECT_EQ(myState(),NestAgent::NestState::PossiblyFull);
	EXPECT_TRUE(runScheduler()); 
}

TEST_F(NestAgentTest, NestBelievesItIsFullAndContactsCameraTest){
	PartType partA = PartType::A;
	agent.msgPleaseGetParts(partA);
	agent.msgIThinkYoureFull();
	EXPECT_CALL(camera, msgIThinkImFull(partA));
	agent.pickAndExecuteAnAction();
	EXPECT_EQ(myState(),NestAgent::NestState::None);
	EXPECT_FALSE(runScheduler());
}

TEST_F(NestAgentTest, NestIsToldItIsStableByCameraTest){
	PartType partA = PartType::A;
	Picture p = Picture::Stable;
	agent.msgPleaseGetParts(partA);
	agent.pickAndExecuteAnAction();
	agent.msgHereIsAPicture(p);
	EXPECT_EQ(myState(), NestAgent::NestState::GoodPicture);
	EXPECT_CALL(partRobot, msgImStable(&agent));
	EXPECT_EQ(runScheduler(), true);
	EXPECT_EQ(myState(), NestAgent::NestState::None);
	EXPECT_FALSE(runScheduler());
	EXPECT_FALSE(runScheduler());
}

TEST_F(NestAgentTest, NestIsToldItIsNotStableByCameraTest){
	PartType partA = PartType::A;
	Picture p = Picture::Unstable;
	agent.msgPleaseGetParts(partA);
	agent.pickAndExecuteAnAction();
	agent.msgHereIsAPicture(p);
	EXPECT_EQ(myState(), NestAgent::NestState::None);
	EXPECT_EQ(runScheduler(), false);
	EXPECT_EQ(myState(), NestAgent::NestState::None);
	EXPECT_EQ(runScheduler(), false);
}

/*TEST_F(NestAgentTest, SendingNewPartTypeToLane){
	PartType partA;
	agent->msgPleaseGetParts(partA);
	EXPECT_EQ(myState(),Purge);
	EXPECT_EQ(runScheduler(),true);
	EXPECT_CALL(lane, msgPleaseGetParts(partA));
}*/